﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Net.Mail;
using System.IO;
using System.Transactions;

namespace FastShip88
{

   
    public static class Utility
    {
        public enum LogLevel
        {
            Error =1,
            Warning,
            Information
        }

        public enum EmailTypes
        {
            ParcelInboundNotification = 1,
            ParcelSplitComplete,
            ParcelSplitFail,
            ParcelCombineFail,
            PayParcelFee,
            ParcelTransferred,
            ParcelTransferDeliverred,
            ParcelReturnDeliverred,
            ParcelCombineComplete,
            UserCreated
        }

        public static HttpServerUtility Server = null;  

        public static int GetUserId(System.Web.UI.Page page)
        {
            int userId = 0;
            if (page.Session["UserId "] == null)
            {
                System.Guid guidUser = (System.Guid)Membership.GetUser().ProviderUserKey;

                DBAccess.UsersDataContext db = new DBAccess.UsersDataContext();
                var users = db.UserInfos;
                var q_users = (from u in users
                               where u.UserId == guidUser
                               select u);
                if (q_users.Count() > 0)
                {
                    var q = q_users.First();
                    userId = q.Id;
                    page.Session["UserId"] = userId.ToString();
                }
                else
                {
                    Log(LogLevel.Error, "No user id for user key " + guidUser.ToString() );
                }
            }
            else
            {
                int.TryParse(page.Session["UserId"].ToString(), out userId);
            }
            
            return userId;
        }

        public static int GetUserIdByUserName(string strUserName)
        {
            DBAccess.UsersDataContext db = new DBAccess.UsersDataContext();
            var q_users = from u in db.aspnet_Users from ui in db.UserInfos
                          where u.UserName == strUserName  && u.UserId == ui.UserId
                          select new{ui.Id};

            if (q_users.Count() > 0)
            {
                var q = q_users.First();
                return q.Id;
            }
            else
            {
                return -1;
            }
        }

        public static decimal GetUnitPriceByFeeType(int feeTypeId, int userId)
        {
            DBAccess.UsersDataContext db = new DBAccess.UsersDataContext();
            decimal unitPrice = 0;

            var q_fee = (from q in db.FeeTypes where q.id == feeTypeId select q).First();

            var q_exrate = ( from q in db.ExchangeRates orderby q.Day descending select q).First();

            unitPrice = q_fee.UnitPrice.Value  * (decimal) q_exrate.Rate;

            if(q_fee.Discount.Value  > 0 )
                unitPrice *= (decimal)q_fee.Discount.Value ;


            var q_user = (from q in db.UserInfos from ul in db.UserLevels where q.Id == userId && ul.Id == q.UserLevelId select new { ul.Discount });

            if (q_user.Count() > 0)
            {
                var q = q_user.First();
                if (q.Discount != null && q.Discount > 0  && q.Discount<1 && (feeTypeId == 4 || feeTypeId  == 5)) //目前VIP客户仅对“拆分”和“合并”操作有优惠。
                    unitPrice = unitPrice * (decimal)q.Discount;
            }

            return unitPrice;
        }

        public static string GetUserEmailById(int userId)
        {
            DBAccess.UsersDataContext db = new DBAccess.UsersDataContext();
            string email = "";

            var q_users = from u in db.UserInfos
                          where  u.Id == userId
                          select new { u.Email};

            if (q_users.Count() > 0)
            {
                var q = q_users.First();
                if (q.Email != null)
                    email = q.Email;
            }

            return email;
        }

        public static void UpdateParcelStatus(int parcelId, byte statusId)
        {
            DBAccess.UsersDataContext db = new DBAccess.UsersDataContext();

            try
            {
                var q = (from p in db.ParcelInfos where p.Id == parcelId select p).First();

                q.StatusId = statusId;
                db.SubmitChanges();
            }
            catch (Exception ex)
            {
                Log(LogLevel.Error, ex.Message);
            }
        }


        public static void RecordPayment(int billId, decimal totalAmount)
        {
            DBAccess.UsersDataContext db;
            db = new DBAccess.UsersDataContext();

            

            using (TransactionScope ts = new TransactionScope())
            {
                try
                {
                    var q_bill = (from q in db.UserBills
                                  where q.Id == billId
                                  select q).First();

                    if(q_bill.IsCleared )
                    {
                        Log(LogLevel.Information, "Bill with ID " + billId.ToString() + " has been already cleared.");
                        
                        return;
                    }
                    var q_new = new DBAccess.UserBill();
                    q_new.FeeTypeId = 14; /*支付宝收款*/
                    q_new.Amount = totalAmount;
                    q_new.Date = DateTime.Now;
                    q_new.IsCancelled = false;
                    q_new.IsCleared = true;
                    db.UserBills.InsertOnSubmit(q_new);
                    db.SubmitChanges();
                    int new_billID = q_new.Id;


                    int transReqId = 0;
                    transReqId = q_bill.TransReqId.HasValue ? q_bill.TransReqId.Value : 0;

                    q_bill.ClearFrom = new_billID;
                    q_bill.IsCleared = true;
                    db.SubmitChanges();

                    var q_parcels = from q in db.ParcelInfos
                                    where q.TransferReqId == transReqId
                                    select q;
                    foreach (var q in q_parcels)
                    {
                        q.StatusId = 90; /*付费完成*/
                        db.SubmitChanges();
                    }

                }
                catch (Exception ex)
                {
                    Utility.Log(Utility.LogLevel.Error, "Ex happens when recording the Ali payment for parcels: " + ex.Message);
                    return;
                }

                ts.Complete();

            }

        }

        public static void SendEmail(EmailTypes emailType, int userId, string otherInfo)
        {
            string emailTo = GetUserEmailById(userId);
            string emailSubject;
            string emailFrom ="info@fastship88.com";
			string emailBody = "";
            string emailParcelInfo = "";
            string mailServerName ="relay-hosting.secureserver.net"; // "fastship88.com"; 
            string emailFile = Server.MapPath("\\MailTemplate.htm");
            string emailFileContent = "";

            if (System.IO.File.Exists(emailFile))
            {
                System.IO.StreamReader sr = new System.IO.StreamReader(emailFile);
                emailFileContent = sr.ReadToEnd();
                sr.Close();
            }
            else
            {
                Log(LogLevel.Error, "Can't find email template file.");
                return;
            }

            if (emailTo != "")
            {
                switch (emailType)
                {
                    case EmailTypes.ParcelInboundNotification:
                        emailSubject = "包裹到达通知";
                        emailParcelInfo = "您的包裹已经到达本网站的物流中心，包裹编号为：" + otherInfo;
                        break;
                    case EmailTypes.ParcelSplitComplete:
                        emailSubject = "包裹拆分完成";
                        emailParcelInfo = "包裹（编号为：" + otherInfo +"）的拆分操作已经完成";
                        break;
                    case EmailTypes.ParcelSplitFail:
                        emailSubject = "合并拆分失败";
                        emailParcelInfo = "包裹拆分操作未能成功，包裹编号为：" + otherInfo +"。具体原因请查看该包裹的系统备注。";
                        break;
                    case EmailTypes.ParcelCombineComplete:
                        emailSubject = "完成合并新包裹";
                        emailParcelInfo = "包裹合并操作已完成，新的包裹系统编号为：" + otherInfo;
                        break;
                    case EmailTypes.ParcelCombineFail:
                        emailSubject = "合并新包裹失败";
                        emailParcelInfo = "包裹合并操作未能成功，具体原因请查看原来（子）包裹的系统备注。";
                        break;

                    case EmailTypes.ParcelTransferred:
                        emailSubject = "包裹发出";
                        emailParcelInfo = "中转请求（系统编号为：" + otherInfo + "）相关的包裹已经发出";
                        break;

                    case EmailTypes.UserCreated:
                        emailSubject = "网站用户创建成功";
                        emailParcelInfo = otherInfo;
                        break;

                    default:
                        emailSubject = "";
                        break;
                }

                emailBody  = emailFileContent.Replace("XXTITLE", emailSubject);
                emailBody = emailBody.Replace("XXBODY", emailParcelInfo);


                try
                {
                    // MailMessage is used to represent the e-mail being sent
                    using (MailMessage message =
                        new MailMessage(emailFrom, emailTo, emailSubject, emailBody))
                    {
                        message.IsBodyHtml = true;
                        message.CC.Add( emailFrom);

                        // SmtpClient is used to send the e-mail
                        SmtpClient mailClient = new SmtpClient(mailServerName, 25);

                        // UseDefaultCredentials tells the mail client to use the 
                        // Windows credentials of the account (i.e. user account) 
                        // being used to run the application
                        mailClient.UseDefaultCredentials = false;
                       

                        mailClient.Credentials = new System.Net.NetworkCredential(emailFrom, "sunrise88");

                        mailClient.EnableSsl = false;


                        Log(LogLevel.Information, "start sending to :" + emailTo);

                        // Send delivers the message to the mail server
                        mailClient.Send(message);
                        Log(LogLevel.Information, "End sending." );
                    }
                    Console.WriteLine("Message sent.");
                }
                catch (FormatException ex)
                {
                    Log(LogLevel.Error, ex.Message);
                }
                catch (SmtpException ex)
                {
                    Log(LogLevel.Error, ex.Message);
                }




            }
        }

        public static void Log(LogLevel level, string info)
        {
            string path = Server.MapPath("\\Log\\Log.txt");

            StreamWriter sw = new StreamWriter(path, true);

           
            sw.WriteLine(DateTime.Now.ToLongTimeString() + ":    " + level.ToString() + ":    " + info);
            sw.WriteLine();

            sw.Close();
            
        }

    }

    public class SafeConvert
    {
        private static DateTime _invalidSQLDateTime = new DateTime(599266080000000000);

        /// <summary>
        /// Convert without exception, when exception happens, return 0;
        /// </summary>
        /// <param name="pVal"></param>
        /// <returns></returns>
        public static int ToInt(object pVal)
        {
            try
            {
                return Convert.ToInt32(pVal);
            }
            catch
            {
                return 0;
            }
        }
        public static int? ToIntOrNull(object pVal)
        {
            try
            {
                return Convert.ToInt32(pVal);
            }
            catch
            {
                return null;
            }
        }

        public static bool ToBool(object pVal)
        {
            try
            {
                return Convert.ToBoolean(pVal);
            }
            catch
            {
                if (pVal.ToString() == "true")
                    return true;

                return false;
            }
        }
        /// <summary>
        /// Convert without exception, when exception happens, return 0.0;
        /// </summary>
        /// <param name="pVal"></param>
        /// <returns></returns>
        public static double ToDouble(object pVal)
        {
            try
            {
                return Convert.ToDouble(pVal);
            }
            catch
            {
                return 0.0;
            }
        }

        /// <summary>
        /// Convert without exception, when exception happens, return DateTime.MinValue;
        /// </summary>
        /// <param name="pVal"></param>
        /// <returns></returns>
        public static DateTime ToDateTime(object pVal)
        {
            try
            {
                return Convert.ToDateTime(pVal);
            }
            catch
            {
                return InvalidSQLDateTime;
            }
        }

        public static DateTime InvalidSQLDateTime
        {
            get { return _invalidSQLDateTime; }
        }


    };

}
